package com.robot.service;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.robot.constant.Admin;
import com.robot.constant.ScheduleType;
import com.robot.dao.InterfaceMapper;
import com.robot.dao.TestCaseMapper;
import com.robot.dao.TestPlanDetailMapper;
import com.robot.dao.TestPlanMapper;
import com.robot.model.Protocol;
import com.robot.model.TestCase;
import com.robot.model.TestPlanDetailDo;
import com.robot.model.TestPlanDo;
import com.robot.thread.TestPlanTask;
import com.robot.util.SessionUtil;
import com.robot.util.TaskUtil;
import com.robot.vo.ResponseMessage;
import com.robot.vo.TestPlanBuild;
import com.robot.vo.TreeMenu;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: li
 * Date: 2020/3/22
 * Time: 14:08
 * PROJECT：robot
 * PACKAGE: com.robot
 *
 * @author:55324936@qq.com To change this template use File | Settings | File Templates.
 */
@Service
@Slf4j
public class TestPlanService {
    @Autowired
    TestPlanMapper testPlanMapper;
    @Autowired
    InterfaceMapper interfaceMapper;
    @Autowired
    TestCaseMapper testCaseMapper;
    @Autowired
    RunTestService runTestService;
    @Autowired
    BuildTestService buildTestService;
    @Autowired
    ThreadPoolTaskExecutor executor;
    @Autowired
    TaskUtil taskUtil;
    @Autowired
    TestPlanDetailMapper testPlanDetailMapper;
    @Autowired
    MailReportService mailReportService;
    /**
     * 新增测试计划
     *
     * @param testPlan
     * @return RequestResult
     */
    @Transactional(rollbackFor = Exception.class)
    public void addTestPlan(TestPlanDo testPlan) {
        testPlanMapper.addPlan(testPlan);
        this.addTask(testPlan);
    }
    public void addTask(TestPlanDo testPlan){
        Integer scheduleTask = testPlan.getScheduleTask();
        if (scheduleTask == ScheduleType.OFF) {
            return;
        }
        String cron= this.timeTask(testPlan);
        TestPlanTask testPlanTask =new TestPlanTask();
        testPlanTask.setBuildTestService(buildTestService);
        testPlanTask.setExecutor(executor);
        testPlanTask.setRunTestService(runTestService);
        testPlanTask.setMailReportService(mailReportService);
        testPlanTask.setTestPlanId(testPlan.getId());
        taskUtil.addTask(cron,testPlanTask);
    }
    /**
     * 用于创建测试计划定时任务
     * @param testPlan
     * **/
    public String timeTask(TestPlanDo testPlan){
        String weekTime = testPlan.getWeekTime();
        List<String> weekTimeList = Splitter.on(",").trimResults().splitToList(weekTime);
        StringBuffer stringBuffer=new StringBuffer();
        for (String s : weekTimeList) {
            switch (s) {
                case "1":
                    stringBuffer.append("MON,");
                    break;
                case "2":
                    stringBuffer.append("TUE,");
                    break;
                case "3":
                    stringBuffer.append("WED,");
                    break;
                case "4":
                    stringBuffer.append("THU,");
                    break;
                case "5":
                    stringBuffer.append("FRI,");
                    break;
                case "6":
                    stringBuffer.append("SAT,");
                    break;
                default:
                    stringBuffer.append("SUN");
                    break;
            }
        }
        String week =stringBuffer.toString();
        if(week.endsWith(",")){
            week =week.substring(0,week.length()-1);
        }
        Integer hhTime = testPlan.getHhTime();
        Integer mmTime = testPlan.getMmTime();
        String cron = "0 " + mmTime + " " + hhTime + " ?  * "+week;
        return cron;
    }
    /**
     * 获取计划列表
     * **/
    public List<TreeMenu> getTestPlanTree(Integer projectId) {
        TestPlanDo testPlan = new TestPlanDo();
        testPlan.setProjectId(projectId);
        List<TestPlanDo> testPlanList = testPlanMapper.getTestPlan(testPlan);
        List<TreeMenu> treeList = Lists.newArrayList();
        //组件测试计划树
        for (TestPlanDo testPlan1 : testPlanList) {
            TreeMenu planTree = new TreeMenu();
            planTree.setIconSkin("icon03");
            planTree.setType("testPlan");
            planTree.setRunMode(testPlan1.getRunMode());
            planTree.setName(testPlan1.getTestPlanName());
            planTree.setId(testPlan1.getId());
            List<TestPlanDetailDo> testPlanDetailList = testPlan1.getTestPlanDetailList();
            if (!CollectionUtils.isEmpty(testPlanDetailList)) {
                List<TreeMenu> list = new ArrayList();
                testPlanDetailList.forEach(testPlanDetailDo -> {
                    TreeMenu treeMenu = new TreeMenu();
                    treeMenu.setName(testPlanDetailDo.getInterfaceAliasName());
                    treeMenu.setType("detail");
                    treeMenu.setId(testPlanDetailDo.getId());
                    list.add(treeMenu);
                });
                planTree.setChildren(list);
            }
            treeList.add(planTree);
        }
        return treeList;
    }
    /**
     * 根据项目id获取计划树
     *
     * @param testPlanId
     * @return Map
     */
    public TestPlanDo getTestPlanById(Integer testPlanId) {
        TestPlanDo testPlan = new TestPlanDo();
        testPlan.setId(testPlanId);
        List<TestPlanDo> testPlanList = testPlanMapper.getTestPlan(testPlan);
        testPlan = testPlanList.get(0);
        return testPlan;
    }

    public void updateTestPlan(TestPlanDo testPlan) {
        testPlanMapper.updateTestPlan(testPlan);
        Integer scheduleTask = testPlan.getScheduleTask();
        if (scheduleTask == ScheduleType.OFF) {
            return;
        }
        String cron= this.timeTask(testPlan);
        TestPlanTask testPlanTask =new TestPlanTask();
        testPlanTask.setBuildTestService(buildTestService);
        testPlanTask.setExecutor(executor);
        testPlanTask.setRunTestService(runTestService);
        testPlanTask.setMailReportService(mailReportService);
        testPlanTask.setTestPlanId(testPlan.getId());
        taskUtil.modify(cron,testPlanTask);
    }
    /**
     * 获取组件列表
     **/
    public ResponseMessage componentListForPlan()
    {
        Integer projectId = SessionUtil.getSessionUser().getLastProjectId();
        Protocol protocol =new Protocol();
        protocol.setProjectId(projectId);
        List<Protocol> protocolList= interfaceMapper.getProtocolList(protocol);
        return ResponseMessage.successResponse(protocolList);
    }
    /**
     * 获取组件和测试用例
     **/
    public TestPlanBuild getComponentAndTestCase(Integer id) {
        Protocol protocol= interfaceMapper.getProtocolById(id);
        TestCase testCaseDo = new TestCase();
        testCaseDo.setInterfaceId(id);
        List<TestCase> testCaseDoList = testCaseMapper.getTestCaseList(testCaseDo);
        TestPlanBuild testPlanBuild=new TestPlanBuild();
        testPlanBuild.setProtocol(protocol);
        testPlanBuild.setTestCaseList(testCaseDoList);
        return testPlanBuild;
    }

    /**
     * 保存测试计划选择的组件和用例信息
     **/
    public ResponseMessage saveComponentTestCase(Integer id, String interfaceAliasName, Integer interfaceId, Integer testPlanId, Integer[] caseIds) {
        TestPlanDetailDo testPlanDetailDo = new TestPlanDetailDo();
        testPlanDetailDo.setInterfaceId(interfaceId);
        testPlanDetailDo.setTestCaseIds(JSON.toJSONString(caseIds));
        testPlanDetailDo.setTestPlanId(testPlanId);
        testPlanDetailDo.setInterfaceAliasName(interfaceAliasName);
        try {
            if (null == id) {
                testPlanDetailMapper.addPlanDetail(testPlanDetailDo);
            } else {
                testPlanDetailDo.setId(id);
                testPlanDetailMapper.updateTestPlanDetail(testPlanDetailDo);
            }
        } catch (Exception e) {
            log.error("增加测试计划明细异常", e);
            return ResponseMessage.errorResponse("增加测试计划明细异常," + Admin.ADMIN_MESSAGE);
        }
        return ResponseMessage.successResponse();
    }
    /**
     * 获取计划详细id
     **/
    public TestPlanDetailDo getComponentTestCaseById(Integer id) {
        TestPlanDetailDo testPlanDetailDo = testPlanDetailMapper.getTestPlanDetailById(id);
        return testPlanDetailDo;
    }
    /**
     * 保存场景化测试计划选择的组件和用例信息
     **/
    public ResponseMessage saveSuiteComponentTestCase(TestPlanDetailDo testPlanDetailDo) {
        try {
            Integer id = testPlanDetailDo.getId();
            if (null == id) {
                testPlanDetailMapper.addPlanDetail(testPlanDetailDo);
            } else {
                testPlanDetailDo.setId(id);
                testPlanDetailMapper.updateTestPlanDetail(testPlanDetailDo);
            }
        } catch (Exception e) {
            log.error("增加测试计划明细异常", e);
            return ResponseMessage.errorResponse("增加测试计划明细异常," + Admin.ADMIN_MESSAGE);
        }
        return ResponseMessage.successResponse();
    }
    /**
     * 删除
     **/
    public ResponseMessage deleteComponentTestCase(Integer id) {
        testPlanDetailMapper.deleteTestPlanDetail(id);
        return ResponseMessage.successResponse();
    }
}
